package Executor;


import interfaces.PrimeCounter;
import interfaces.PrimeFinder;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Runner {

    private int start;
    private int end;
    private int threads;

    private int result;

    private long startTime;
    private long endTime;

    public Runner(int start, int end, int threads) {

        if (end < start) {
            throw new IllegalArgumentException("End number < start number ");
        }

        if (start < 0) {
            throw new IllegalArgumentException("Start number must be positive");
        }

        if (threads < 1) {
            throw new IllegalArgumentException("You need at least 1 threads");
        }
        if (end < 0) {
            throw new IllegalArgumentException("End number must be positive");
        }
        this.start = start;
        this.end = end;
        this.threads = threads;

    }

    public void runWithExecutors() {

        ExecutorService threadpool = Executors.newFixedThreadPool(this.threads);
        PrimeFinder finder = new PrimeFinderImpl();
        finder.setThreadPool(threadpool);

        PrimeCounter counter = new PrimeCounterImpl();
        counter.setThreadPool(threadpool);
        counter.setPrimeFinder(finder);

        start();

        this.result = counter.count(start, end, threads);
        stop();
        threadpool.shutdown();

    }

    public void run() {

        PrimeFinder finder = new PrimeFinderImpl();
        start();

        for (int i = 0; i < threads; i++) {
            Thread t = new Thread(new Counter(start, end, finder));
            t.start();
            // System.out.println("Started Thread:" + i);
        }

        stop();


    }

    private void start() {
        this.startTime = System.currentTimeMillis();
    }

    private void stop() {
        this.endTime = System.currentTimeMillis();
    }

    public int getResult() {
        return result;
    }

    public long getRunningTime() {
        return endTime - startTime;
    }

}
